文件读写
修改文件指针位置
write
系统调用每次打开一个文件都会保存一个指向文件位置的指针, 当读写操作完成时, 指针会移动到下一个记录位置, 这个指针于文件描述符相关联.这种情况下, 我们如何修改文件中的内容. 答案是系统调用lseek
改变文件当前位置
指针是与文件描述符项关联, 而不是与文件关联, 所以如果两个程序同时打开一个文件, 这时会有两个指针, 两个程序对文件的读操作不会互相干扰.
系统调用lseek
可以改变已打开文件的当前位置,
lseek | |
---|---|
目标 | 使指针指向文件中的指定位置 |
头文件 | #include <sys/type.h> 或者 #include <unistd.h> |
函数原型 | off_t oldpos = lseek(int fd, off_t dist, int base) |
参数 | fd: 文件描述符, dist: 移动的距离 |
base: SEEK_SET 文件开始 SEEK_CUR 当前位置, SEEK_END 文件结尾 | |
返回值 | -1 error, oldpos 指针变化前的位置 |
lseek
改变文件描述符所关联的指针的位置, 新的位置友 dist 和 base 来指定, base 是基准位置, dist 是从基准位置开始的偏移量, 基准位置是从文件的开始(0)、当前位置(1)或文件的结尾(2)
偏移量可以是负的
一些例子
把指针往前偏移一个 utmp 结构
lseek(fd, -(sizeof(struct utmp)), SEEK_CUR);
把指针指到第11个记录的开始位置
lseek(fd, 10 * sizeof(struct utmp), SEEK_SET);
把指针只到文件末尾
lseek(fd, 0, SEEK_END);
返回指针所指向的当前位置
lseek(fd, 0, SEEK_CUR);
终端注销代码
根据上一小节的知识, 可以编写一个函数对注销的用户修改 utmp 中相应的记录
logout_tty(char *line) { int fd; struct utmp rec; int len = sizeof(struct utmp); int reval = -1; if (( fd = open(UTMP_FILE, O_RDWR)) == -1) return -1; while (read(fd, &rec, len) == len) if (strncmp(rec.ut_line, line, sizeof(rec.ut_line)) == 0) { rec.ut_type = DEAD_PROCESS; if (time(&rec.ut_time != -1)) if (lseek(fd, -len, SEEK_CUR) != -1) if (write(fd, &rec, len) == len) retval = 0; break; } if (close(fd) == -1) retval = -1; return retval; }
lseek
将文件指针回退一个 utmp 长度, 并将新的 utmp 写入到文件